BASE_PAGE = "BasePage"
PAGEOBJECT_BASE_ATTRS = ("page_name", "page_path")
PAGEOBJECT_DEFAULT_VAL = ...


class PageObjectBase:
    page_name = ...  # 每个页面应该有 page_name，即页面名称
    page_path = ...  # 每个页面应该有 path_path，即页面地址


# 调用别名
class ApiAlias:
    def __init__(self, alias: str):
        self.alias = alias


# 允许 PageObject 使用函数别名
class _FuncAlias(ApiAlias):
    def __get__(self, instance: object, owner: type):
        self.instance = instance
        return self

    def __call__(self, alias: str):
        self.alias = alias
        return self

    def __getattr__(self, attr):
        if not hasattr(self, "instance"):
            raise AttributeError("不存在别名对象")
        return getattr(getattr(self.instance, self.alias), attr)

    def params(self, *args, **kwargs):
        return getattr(self.instance, self.alias)(*args, **kwargs)

    @property
    def attr(self):
        return getattr(self.instance, self.alias)

    @attr.setter
    def attr(self, value):
        setattr(self.instance, self.alias, value)

    @attr.deleter
    def attr(self):
        delattr(self.instance, self.alias)


class AliasError(Exception):
    pass


class ApiAliasMeta(type):
    def __new__(mcs, name: str, bases: tuple, attrs: dict):
        for attr in dict(attrs).values():
            if isinstance(attr, ApiAlias):
                if attr.alias and attrs.get(attr.alias):
                    raise AliasError(f"{name}中存在重复的别名 '{attr.alias}'")
                attrs[attr.alias] = attr
        return super().__new__(mcs, name, bases, attrs)

    # 设置函数别名
    def __init__(cls, name: str, bases: tuple, attrs: dict):
        cls.func_alias = _FuncAlias("别名调用")  # IDE 联想使用 ...，真tm弱智
        setattr(cls, "别名调用", cls.func_alias)
        super().__init__(name, bases, attrs)
